home *** CD-ROM | disk | FTP | other *** search
- /* $Id: macros.h,v 1.10 2003/04/03 12:20:17 short Exp $
- * Include file with general macros and typedefs used through Captive project
- * Copyright (C) 2002 Jan Kratochvil <project-captive@jankratochvil.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; exactly version 2 of June 1991 is required
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
- #ifndef _CAPTIVE_MACROS_H
- #define _CAPTIVE_MACROS_H 1
-
-
- #include <glib/gmacros.h>
- #include <glib/gmem.h>
- #include <stdarg.h>
- #include <string.h> /* for memset() */
- #include <glib/galloca.h>
- #include <glib/gmessages.h>
- #include <glib/gutils.h> /* for g_snprintf(); glib-2.2.x+ it also has in <glib/gprintf.h> */
-
-
- G_BEGIN_DECLS
-
- /**
- * CAPTIVE_FAKEUSE:
- *
- * Prevent 'might be used uninitialized' warning.
- * Macro will fakes the use of the variable as sometimes GCC can't code flow
- * analyse #C correctly.
- *
- * <informalexample>
- * <programlisting>
- * g_some_type some_variable CAPTIVE_FAKEUSE;
- * </programlisting>
- * </informalexample>
- */
- #define CAPTIVE_FAKEUSE =0
-
-
- /**
- * captive_newn:
- * @objp: Variable with the pointer to the objects wished to be allocated.
- * Original value is discarded.
- * @n: Numbers of objects to be allocated. Value %0 is permitted (%NULL assignment effect).
- *
- * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp.
- * Allocated memory may contain garbage.
- *
- * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp))*n.
- * Value %NULL is returned iff @n==%0;
- */
- #define captive_newn(objp,n) ((objp)=g_new(typeof(*(objp)),(n)))
-
-
- /**
- * captive_new0n:
- * @objp: Variable with the pointer to the objects wished to be allocated and precleared.
- * Original value is discarded.
- * @n: Numbers of objects to be allocated. Value %0 is permitted (%NULL assignment effect).
- *
- * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp.
- * Allocated memory is precleared.
- *
- * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp))*n.
- * Value %NULL is returned iff @n==%0;
- */
- #define captive_new0n(objp,n) ((objp)=g_new0(typeof(*(objp)),(n)))
-
-
- /**
- * captive_renewn:
- * @objp: Variable with the pointer to the objects wished to be reallocated.
- * Value %NULL is permitted (g_malloc() effect).
- * @n: Numbers of objects to be allocated. Value %0 is permitted (g_free() effect).
- *
- * Macro to reallocate the original memory stored in @objp
- * to the size @n objects of type *@objp and to assign the resulting pointer to @objp.
- * New allocated space may contain garbage. Both @objp and @n can be nonexclusively
- * passed as zero.
- *
- * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp))*n.
- * Value %NULL is returned iff @n==%0;
- */
- #define captive_renewn(objp,n) ({ \
- typeof(&(objp)) _captive_renewn_objpp=&(objp); \
- *_captive_renewn_objpp=g_renew(typeof(*(objp)),*_captive_renewn_objpp,(n)); \
- (*_captive_renewn_objpp); \
- })
-
-
- /**
- * captive_new:
- * @objp: Variable with the pointer to the object wished to be allocated.
- * Original value is discarded.
- *
- * Macro to allocate one object of type *@objp and to assign the resulting pointer to @objp.
- * Allocated memory may contain garbage. Equivalent to captive_newn(objp,1) call.
- *
- * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp)).
- * Value %NULL is never returned.
- */
- #define captive_new(objp) (captive_newn((objp),1))
-
-
- /**
- * captive_new0:
- * @objp: Variable with the pointer to the object wished to be allocated and precleared.
- * Original value is discarded.
- *
- * Macro to allocate one object of type *@objp and to assign the resulting pointer to @objp.
- * Allocated memory is precleared. Equivalent to captive_new0n(objp,1) call.
- *
- * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp)).
- * Value %NULL is never returned.
- */
- #define captive_new0(objp) (captive_new0n((objp),1))
-
-
- /**
- * captive_newn_alloca:
- * @objp: Variable with the pointer to the objects wished to be allocated.
- * Original value is discarded.
- * @n: Numbers of objects to be allocated. Value %0 is permitted (%NULL assignment effect).
- *
- * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp.
- * Allocated memory may contain garbage.
- *
- * Memory is allocated on the stack frame by g_alloca() and it will be automatically deallocated
- * during exit of current function (or current block if variable sized variables present there).
- * You cannot deallocate or reallocate such memory in any other way.
- *
- * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp))*n.
- * Value %NULL is returned iff @n==%0;
- */
- #define captive_newn_alloca(objp,n) ({ \
- gsize _captive_newn_alloca_n=(n); \
- /* Fix 'g_alloca(0)!=NULL': */ \
- ((objp)=(!_captive_newn_alloca_n ? NULL : g_alloca(sizeof(*(objp))*_captive_newn_alloca_n))); \
- })
-
-
- /**
- * captive_new0n_alloca:
- * @objp: Variable with the pointer to the objects wished to be allocated and precleared.
- * Original value is discarded.
- * @n: Numbers of objects to be allocated. Value %0 is permitted (%NULL assignment effect).
- *
- * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp.
- * Allocated memory is precleared.
- *
- * Memory is allocated on the stack frame by g_alloca() and it will be automatically deallocated
- * during exit of current function (or current block if variable sized variables present there).
- * You cannot deallocate or reallocate such memory in any other way.
- *
- * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp))*n.
- * Value %NULL is returned iff @n==%0;
- */
- #define captive_new0n_alloca(objp,n) ({ \
- typeof(&(objp)) _captive_new0n_alloca_objpp=&(objp); \
- captive_newn_alloca(*_captive_new0n_alloca_objpp,(n)); \
- CAPTIVE_MEMZERO(*_captive_new0n_alloca_objpp); \
- (*_captive_new0n_alloca_objpp); \
- })
-
-
- /**
- * captive_new_alloca:
- * @objp: Variable with the pointer to the object wished to be allocated.
- * Original value is discarded.
- *
- * Macro to allocate one object of type *@objp and to assign the resulting pointer to @objp.
- * Allocated memory may contain garbage. Equivalent to captive_newn_alloca(objp,1) call.
- *
- * Memory is allocated on the stack frame by g_alloca() and it will be automatically deallocated
- * during exit of current function (or current block if variable sized variables present there).
- * You cannot deallocate or reallocate such memory in any other way.
- *
- * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp)).
- * Value %NULL is never returned.
- */
- #define captive_new_alloca(objp) (captive_newn_alloca((objp),1))
-
-
- /**
- * captive_new0_alloca:
- * @objp: Variable with the pointer to the object wished to be allocated and precleared.
- * Original value is discarded.
- *
- * Macro to allocate one object of type *@objp and to assign the resulting pointer to @objp.
- * Allocated memory is precleared. Equivalent to captive_new0n_alloca(objp,1) call.
- *
- * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp)).
- */
- #define captive_new0_alloca(objp) (captive_new0n_alloca((objp),1))
-
-
- /**
- * captive_memdup:
- * @destp: Variable with the pointer to the target object wished to be allocated.
- * Original value is discarded.
- * @srcp: Pointer to the source object to be copied to @destp.
- *
- * Macro to similiar to g_memdup() but the object size is detected automatically.
- * Size of @destp object and @srcp object must be the same.
- *
- * You must free the allocated memory of @destp by g_free().
- *
- * @Returns: Initialized @destp value as the copied memory of size #sizeof(typeof(*srcp)).
- */
- #define captive_memdup(destp,srcp) ({ \
- typeof(&(destp)) _captive_captive_memdup_destpp=&(destp); \
- g_assert(sizeof(*(destp))==sizeof(*(srcp))); \
- captive_new(*_captive_captive_memdup_destpp); \
- memcpy(*_captive_captive_memdup_destpp,(srcp),sizeof(*(srcp))); \
- (*_captive_captive_memdup_destpp); \
- })
-
-
- /**
- * captive_va_arg:
- * @objp: Variable to be filled from the next argument of @ap.
- * @ap: Initialized #va_list type.
- *
- * Automatically determines the size of @objp.
- * Equivalent to objp=va_arg(ap,typeof(objp)) call.
- *
- * @Returns: Initialized @objp value.
- */
- #define captive_va_arg(objp,ap) ((objp)=va_arg((ap),typeof(objp)))
-
-
- /**
- * CAPTIVE_MEMZERO:
- * @objp: Pointer to the variable to be cleared.
- *
- * Clears the sizeof(*@objp) bytes of the given pointer with memset().
- * Pass _pointer_ to the object to be cleared.
- */
- #define CAPTIVE_MEMZERO(objp) (memset((objp),0,sizeof(*(objp))))
-
-
- /**
- * captive_printf_alloca:
- * @format: Format string. See the sprintf() documentation.
- * @args...: Arguments for @format. See the sprintf() documentation.
- *
- * Format the given format string @format as in sprintf().
- * Output buffer is allocated automatically and it does not need to be deallocated
- * manually as it is managed by g_alloca().
- *
- * @Returns: Formatted output string located in g_alloca() memory.
- */
- #define captive_printf_alloca(format,args...) ({ \
- gsize _captive_printf_alloca_size=captive_nv_printf_string_upper_bound((format) , ## args); \
- gchar *_captive_printf_alloca_r=g_alloca(_captive_printf_alloca_size); \
- g_snprintf(_captive_printf_alloca_r,_captive_printf_alloca_size,(format) , ## args); \
- (const gchar *)_captive_printf_alloca_r; \
- })
- static inline gsize captive_nv_printf_string_upper_bound(const gchar *format,...) G_GNUC_PRINTF(1,0) G_GNUC_UNUSED;
- static inline gsize captive_nv_printf_string_upper_bound(const gchar *format,...)
- {
- va_list ap;
- gsize r;
-
- va_start(ap,format);
- r=g_printf_string_upper_bound(format,ap);
- va_end(ap);
- return r;
- }
-
-
- /**
- * captive_strdup_alloca:
- * @string: #const #gchar * string to duplicate.
- *
- * Macro to do g_strdup() equivalent in g_alloca() style.
- *
- * Memory is allocated on the stack frame by g_alloca() and it will be automatically deallocated
- * during exit of current function (or current block if variable sized variables present there).
- * You cannot deallocate or reallocate such memory in any other way.
- *
- * @Returns: Duplicated @string. You may modify its items if the length is not changed.
- */
- #define captive_strdup_alloca(string) ({ \
- const gchar *_captive_strdup_alloca_string=(string); \
- const gchar *_captive_strdup_alloca_r=g_alloca(strlen(_captive_strdup_alloca_string)+1); \
- strcpy((gchar *)_captive_strdup_alloca_r,_captive_strdup_alloca_string); \
- (const gchar *)(_captive_strdup_alloca_r); \
- })
-
-
- /**
- * CAPTIVE_ROUND_DOWN:
- * @pointer: Arbitrary pointer type.
- * @fragment: Amount of 'sizeof(char)' to align @pointer down to.
- * This size will be typically a power of 2.
- * Value less or equal to %0 is forbidden.
- *
- * General pointer down-rounding macro. Already aligned pointer is left as is.
- *
- * glib NOTE: YOU MAY NOT STORE POINTERS IN INTEGERS.
- *
- * @Returns: Down-rounded @pointer to the integer multiple of @fragment.
- * Resulting pointer has the same type as @pointer.
- */
- #define CAPTIVE_ROUND_DOWN(pointer,fragment) \
- ((typeof(pointer))(((guint32)(pointer))-CAPTIVE_ROUND_DOWN_EXCEEDING((pointer),(fragment))))
- #define CAPTIVE_ROUND_DOWN64(pointer,fragment) \
- ((typeof(pointer))(((guint64)(pointer))-CAPTIVE_ROUND_DOWN_EXCEEDING64((pointer),(fragment))))
-
-
- /**
- * CAPTIVE_ROUND_DOWN_EXCEEDING:
- * @pointer: Arbitrary pointer type.
- * @fragment: Amount of 'sizeof(char)' to detect down-alignment amount of @pointer for.
- * This size will be typically a power of 2.
- * Value less or equal to %0 is forbidden.
- *
- * Detects current non-aligned amount of data exceeding over integer multiple of @fragment.
- * It will return value %0 for an aligned pointer.
- *
- * glib NOTE: YOU MAY NOT STORE POINTERS IN INTEGERS.
- *
- * @Returns: #gsize typed number of bytes exceeding over integer multiple of @fragment.
- */
- #define CAPTIVE_ROUND_DOWN_EXCEEDING(pointer,fragment) \
- ((gsize)(((guint32)(pointer))%(fragment)))
- #define CAPTIVE_ROUND_DOWN_EXCEEDING64(pointer,fragment) \
- ((gsize)(((guint64)(pointer))%(fragment)))
-
-
- /**
- * CAPTIVE_ROUND_UP:
- * @pointer: Arbitrary pointer type.
- * @fragment: Amount of 'sizeof(char)' to align @pointer up to.
- * This size will be typically a power of 2.
- * Value less or equal to %0 is forbidden.
- *
- * General pointer up-rounding macro. Already aligned pointer is left as is.
- *
- * glib NOTE: YOU MAY NOT STORE POINTERS IN INTEGERS.
- *
- * @Returns: Up-rounded @pointer to the integer multiple of @fragment.
- * Resulting pointer has the same type as @pointer.
- */
- #define CAPTIVE_ROUND_UP(pointer,fragment) \
- /* new retyping as 'pointer' gets passed as 'char *' to CAPTIVE_ROUND_DOWN(). */ \
- ((typeof(pointer))(CAPTIVE_ROUND_DOWN(((guint32)(pointer))+(fragment)-1,(fragment))))
- #define CAPTIVE_ROUND_UP64(pointer,fragment) \
- /* new retyping as 'pointer' gets passed as 'char *' to CAPTIVE_ROUND_DOWN(). */ \
- ((typeof(pointer))(CAPTIVE_ROUND_DOWN64(((guint64)(pointer))+(fragment)-1,(fragment))))
-
- G_END_DECLS
-
-
- #endif /* _CAPTIVE_MACROS_H */
-